package com.androidgame.framework.impl;

import java.io.IOException;
import java.io.InputStream;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;

import com.androidgame.framework.Graphics;
import com.androidgame.framework.Pixmap;

//stores the canvas and the frame buffer 
public class AndroidGraphics implements Graphics 
{

	//use to load Bitmap instances
	AssetManager assets;

	//represents our artificial framebuffer
	Bitmap frameBuffer;

	//used to draw the artificial framebuffer
	Canvas canvas;

	Paint paint;
	Rect srcRect = new Rect();
	Rect dstRect = new Rect();

	public AndroidGraphics(AssetManager assets, Bitmap frameBuffer) 
	{
		this.assets = assets;
		this.frameBuffer = frameBuffer;
		this.canvas = new Canvas(frameBuffer);
		this.paint = new Paint();
	}

	//method will load an image asset in our applications APK file
	public Pixmap newPixmap(String fileName, PixmapFormat format) 
	{
		
		// set the pixel format
		Config config = null;
		if (format == PixmapFormat.RGB565)
		{
			config = Config.RGB_565;
		}

		else if (format == PixmapFormat.ARGB4444)
		{
			config = Config.ARGB_4444;
		}

		else
		{
			config = Config.ARGB_8888;
		}

		//create a new Options instance and set
		//our preferred color format
		Options options = new Options();

		options.inPreferredConfig = config;

		InputStream in = null;

		Bitmap bitmap = null;

		//load the Bitmap from the asset via the BitmapFactory
		try 
		{
			in = assets.open(fileName);
			bitmap = BitmapFactory.decodeStream(in);
			
			if (bitmap == null)
			{
				throw new RuntimeException("Couldn't load bitmap from asset '"
						+ fileName + "'");
			}
		} 

		catch (IOException e) 
		{
			throw new RuntimeException("Couldn't load bitmap from asset '"
					+ fileName + "'");
		} 

		finally 
		{
			if (in != null) 
			{
				try 
				{
					in.close();
				} 

				catch (IOException e) 
				{
				}
			}
		}
		
		//check what format the BitmapFactory used to load the 
		//Bitmap and translate it into a PixmapFormat enumeration value
		if (bitmap.getConfig() == Config.RGB_565)
		{
			format = PixmapFormat.RGB565;
		}
		
		else if (bitmap.getConfig() == Config.ARGB_4444)
		{
			format = PixmapFormat.ARGB4444;
		}
		
		else
		{
			format = PixmapFormat.ARGB8888;
		}
		
		//return a new Pixmap
		return new AndroidPixmap(bitmap, format);
	}

	//clears the complete framebuffer with the given color
	public void clear(int color) 
	{
		canvas.drawRGB((color & 0xff0000) >> 16, (color & 0xff00) >> 8,
				(color & 0xff));
	}

	//set the pixel at (x,y) in the framebuffer to the given color
	public void drawPixel(int x, int y, int color) 
	{
		paint.setColor(color);
		canvas.drawPoint(x, y, paint);
	}

	public void drawLine(int x, int y, int x2, int y2, int color) 
	{
		paint.setColor(color);
		canvas.drawLine(x, y, x2, y2, paint);
	}

	public void drawRect(int x, int y, int width, int height, int color) 
	{
		paint.setColor(color);
		paint.setStyle(Style.FILL);
		canvas.drawRect(x, y, x + width - 1, y + width - 1, paint);
	}

	public void drawPixmap(Pixmap pixmap, int x, int y, int srcX, int srcY,
			int srcWidth, int srcHeight) 
	{
		srcRect.left = srcX;
		srcRect.top = srcY;
		srcRect.right = srcX + srcWidth - 1;
		srcRect.bottom = srcY + srcHeight - 1;
		dstRect.left = x;
		dstRect.top = y;
		dstRect.right = x + srcWidth - 1;
		dstRect.bottom = y + srcHeight - 1;
		canvas.drawBitmap(((AndroidPixmap) pixmap).bitmap, srcRect, dstRect,
				null);
	}

	public void drawPixmap(Pixmap pixmap, int x, int y) 
	{
		canvas.drawBitmap(((AndroidPixmap)pixmap).bitmap, x, y, null);
	}

	//return the width and height of the framebuffer in pixels
	public int getWidth() 
	{
		return frameBuffer.getWidth();
	}

	public int getHeight() 
	{
		return frameBuffer.getHeight();
	}
}